package life.kenny.community.service.impl;

import life.kenny.community.dto.PagenationDto;
import life.kenny.community.dto.QuestionDTO;
import life.kenny.community.dto.QuestionQueryDTO;
import life.kenny.community.enums.SortEnum;
import life.kenny.community.exception.CustomizeErrorCode;
import life.kenny.community.exception.CustomizeException;
import life.kenny.community.mapper.QuestionExtMapper;
import life.kenny.community.mapper.QuestionMapper;
import life.kenny.community.mapper.UserMapper;
import life.kenny.community.model.Question;
import life.kenny.community.model.QuestionExample;
import life.kenny.community.model.User;
import life.kenny.community.model.UserExample;
import life.kenny.community.service.QuestionService;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thymeleaf.standard.expression.Each;

import javax.print.attribute.standard.RequestingUserName;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Jay
 * @date 2021/10/8 4:31 下午
 */
@Service
public class QuestionServiceImpl implements QuestionService {

    @Autowired
    private QuestionMapper questionMapper;

    @Autowired
    private QuestionExtMapper questionExtMapper;
    @Autowired
    private UserMapper userMapper;


    @Override
    public void createOrUpdate(Question question) {
        //question里无id则新增
        if (question.getId() == null) {
            //创建
            question.setGmtCreate(System.currentTimeMillis());
            question.setGmtModified(question.getGmtCreate());
            question.setViewCount(0);
            question.setCommentCount(0);
            question.setLikeCount(0);
            question.setSticky(0);
            questionMapper.insert(question);
        }else{
            //否则就更新
            Question dbQuestion = questionMapper.selectByPrimaryKey(question.getId());
            if (dbQuestion == null) {
                System.out.println("question not found.");
            }
            if (dbQuestion.getCreator() != question.getCreator()) {
                System.out.println("invalid operation.");
            }
            Question updateQuestion = new Question();
            BeanUtils.copyProperties(question,updateQuestion);
            updateQuestion.setGmtCreate(System.currentTimeMillis());
            QuestionExample example = new QuestionExample();
            example.createCriteria()
                    .andIdEqualTo(dbQuestion.getId());
            questionMapper.updateByExampleSelective(updateQuestion, example);
        }

    }

    @Override
    public PagenationDto list(Integer page,Integer size,String tag,String search,String sort) {
        //处理search
        if (StringUtils.isNotBlank(search)) {
            String[] tags = StringUtils.split(search, " ");
            search = Arrays
                    .stream(tags)
                    .filter(StringUtils::isNotBlank)
                    .map(t -> t.replace("+", "").replace("*", "").replace("?", ""))
                    .filter(StringUtils::isNotBlank)
                    .collect(Collectors.joining("|"));
        }

        PagenationDto pagenationDto = new PagenationDto();
        Integer totalPage;

        QuestionQueryDTO questionQueryDTO = new QuestionQueryDTO();
        questionQueryDTO.setSearch(search);
        if (StringUtils.isNotBlank(tag)) {
            tag = tag.replace("+", "").replace("*", "").replace("?", "");
            questionQueryDTO.setTag(tag);
        }
        //排序的enum
        for (SortEnum sortEnum : SortEnum.values()) {
            if (sortEnum.name().toLowerCase().equals(sort)) {
                questionQueryDTO.setSort(sort);

                if (sortEnum == SortEnum.HOT7) {
                    questionQueryDTO.setTime(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 7);
                }
                if (sortEnum == SortEnum.HOT30) {
                    questionQueryDTO.setTime(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30);
                }
                break;
            }
        }
        //计算总条数
        QuestionExample example = new QuestionExample();
        example.createCriteria();
        int totalCount = questionExtMapper.countBySearch(questionQueryDTO);
        //int totalCount = questionMapper.countByExample(example);
        if (totalCount % size == 0) {
            totalPage = totalCount / size;
        } else {
            totalPage = totalCount / size + 1;
        }
        if (page < 1) {
            page = 1;
        }
        if (page > totalPage) {
            page = totalPage;
        }
        pagenationDto.setPagenation(totalPage,page);
        //计算起始页
        Integer offset = page < 1 ? 0 : size * (page - 1);

        questionQueryDTO.setSize(size);
        questionQueryDTO.setPage(offset);

        example.setOrderByClause("gmt_create desc");
        // List<Question> questions = questionMapper.selectByExampleWithRowbounds(example, new RowBounds(offset, size));
        List<Question> questions = questionExtMapper.selectBySearch(questionQueryDTO);
        List<QuestionDTO> questionDTOS = new ArrayList<>();

        for (Question question : questions) {
            UserExample userExample = new UserExample();
            QuestionDTO questionDTO = new QuestionDTO();
            BeanUtils.copyProperties(question,questionDTO);
            if (question.getCreator() != null) {
                userExample.createCriteria()
                        .andAccountIdEqualTo(String.valueOf(question.getCreator()));
                List<User> users = userMapper.selectByExample(userExample);
                if(users.size() > 0){
                    questionDTO.setUser(users.get(0));
                }
            }
            questionDTOS.add(questionDTO);
        }
        // 缓存。


        pagenationDto.setData(questionDTOS);
        return pagenationDto;
    }

    @Override
    public PagenationDto listByUserId(Integer page, Integer size, Long accountId) {
        PagenationDto pagenationDto = new PagenationDto();
        Integer totalPage;
        //计算总条数
        QuestionExample example = new QuestionExample();
        example.createCriteria()
                .andCreatorEqualTo(accountId);
        int totalCount = questionMapper.countByExample(example);
        if (totalCount % size == 0) {
            totalPage = totalCount / size;
        } else {
            totalPage = totalCount / size + 1;
        }
        if (page < 1) {
            page = 1;
        }
        if (page > totalPage) {
            page = totalPage;
        }
        pagenationDto.setPagenation(totalPage,page);
        //计算起始页
        Integer offset = page < 1 ? 0 : size * (page - 1);
        List<Question> questions = questionMapper.selectByExampleWithRowbounds(example, new RowBounds(offset, size));
        List<QuestionDTO> questionDTOS = new ArrayList<>();
        UserExample userExample = new UserExample();
        for (Question question : questions) {
            QuestionDTO questionDTO = new QuestionDTO();
            BeanUtils.copyProperties(question,questionDTO);
            if (question.getCreator() != null) {
                userExample.createCriteria()
                        .andAccountIdEqualTo(String.valueOf(question.getCreator()));
                List<User> users = userMapper.selectByExample(userExample);
                if(users.size() > 0){
                    questionDTO.setUser(users.get(0));
                }
            }
            questionDTOS.add(questionDTO);
        }
        pagenationDto.setData(questionDTOS);
        return pagenationDto;
    }

    @Override
    public QuestionDTO getByQuestionId(Long id) {
        Question question = questionMapper.selectByPrimaryKey(id);
        if (question == null) {
            throw new CustomizeException(CustomizeErrorCode.QUESTION_NOT_FOUND);
        }
        QuestionDTO questionDTO = new QuestionDTO();
        BeanUtils.copyProperties(question, questionDTO);
        UserExample example = new UserExample();
        if (question.getCreator() != null) {
            example.createCriteria()
                    .andAccountIdEqualTo(String.valueOf(question.getCreator()));
            List<User> users = userMapper.selectByExample(example);
            if (users.size() > 0) {
                questionDTO.setUser(users.get(0));
            }
        }

        return questionDTO;
    }

    @Override
    public void incView(Long id) {
        Question question = questionMapper.selectByPrimaryKey(id);
        question.setViewCount(1);
        questionExtMapper.incView(question);
    }

    @Override
    public List<QuestionDTO> selectRelated(QuestionDTO queryDTO) {
        //校验
        if (StringUtils.isBlank(queryDTO.getTag())) {
            return new ArrayList<>();
        }
        String[] tags = StringUtils.split(queryDTO.getTag(), ",");

        String regexpTag = Arrays.stream(tags)
                .filter(StringUtils::isNotBlank)
                .map(t -> t.replace("+", "")
                        .replace("*", "")
                        .replace("?", ""))
                .filter(StringUtils::isNotBlank)
                .collect(Collectors.joining("|"));
        //joining(CharSequence delimiter)
        //返回一个 Collector ，按照遇到的顺序连接由指定的分隔符分隔的输入元素。
        Question question = new Question();
        question.setId(queryDTO.getId());
        question.setTag(regexpTag);

        List<Question> questions = questionExtMapper.selectRelated(question);
        List<QuestionDTO> questionDTOS = questions.stream()
                .map(question1 -> {
                    QuestionDTO questionDTO = new QuestionDTO();
                    BeanUtils.copyProperties(question1, questionDTO);
                    return questionDTO;
                }).collect(Collectors.toList());
        return questionDTOS;
    }
}
